home *** CD-ROM | disk | FTP | other *** search
- /* $Id: varray.c,v 1.9 1997/01/30 21:05:03 brianp Exp $ */
-
- /*
- * Mesa 3-D graphics library
- * Version: 2.2
- * Copyright (C) 1995-1997 Brian Paul
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- * $Log: varray.c,v $
- * Revision 1.9 1997/01/30 21:05:03 brianp
- * moved gl_GetPointerv() to get.c
- *
- * Revision 1.8 1996/12/18 20:00:57 brianp
- * gl_set_material() now takes a bitmask instead of face and pname
- *
- * Revision 1.7 1996/12/07 10:21:28 brianp
- * call gl_set_material() instead of gl_Materialfv()
- *
- * Revision 1.6 1996/11/09 03:12:34 brianp
- * now call gl_render_vb() after gl_transform_vb_part2() call
- *
- * Revision 1.5 1996/10/08 00:05:06 brianp
- * added some missing stuff to gl_ArrayElement()
- *
- * Revision 1.4 1996/10/04 02:37:06 brianp
- * gl_ArrayElement() wasn't always initializing vertex Z and W values
- *
- * Revision 1.3 1996/10/03 00:47:56 brianp
- * added #include <stdlib.h> for abort()
- *
- * Revision 1.2 1996/09/27 01:33:07 brianp
- * added missing default cases to switches
- *
- * Revision 1.1 1996/09/13 01:38:16 brianp
- * Initial revision
- *
- */
-
-
-
- /*
- * NOTE: At this time, only three vertex array configurations are optimized:
- * 1. glVertex3fv(), zero stride
- * 2. glNormal3fv() with glVertex3fv(), zero stride
- * 3. glNormal3fv() with glVertex4fv(), zero stride
- *
- * More optimized array configurations can be added.
- */
-
-
-
-
- #include <stdlib.h>
- #include <string.h>
- #include "draw.h"
- #include "context.h"
- #include "enable.h"
- #include "dlist.h"
- #include "light.h"
- #include "macros.h"
- #include "types.h"
- #include "varray.h"
- #include "vb.h"
- #include "xform.h"
-
-
-
- void gl_VertexPointer( GLcontext *ctx,
- GLint size, GLenum type, GLsizei stride,
- const GLvoid *ptr )
- {
- if (size<2 || size>4) {
- gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
- return;
- }
- if (stride<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
- return;
- }
- switch (type) {
- case GL_SHORT:
- ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLshort);
- break;
- case GL_INT:
- ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLint);
- break;
- case GL_FLOAT:
- ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLfloat);
- break;
- case GL_DOUBLE:
- ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLdouble);
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
- return;
- }
- ctx->Array.VertexSize = size;
- ctx->Array.VertexType = type;
- ctx->Array.VertexStride = stride;
- ctx->Array.VertexPtr = (void *) ptr;
- }
-
-
-
-
- void gl_NormalPointer( GLcontext *ctx,
- GLenum type, GLsizei stride, const GLvoid *ptr )
- {
- if (stride<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
- return;
- }
- switch (type) {
- case GL_BYTE:
- ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLbyte);
- break;
- case GL_SHORT:
- ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLshort);
- break;
- case GL_INT:
- ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLint);
- break;
- case GL_FLOAT:
- ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLfloat);
- break;
- case GL_DOUBLE:
- ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLdouble);
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
- return;
- }
- ctx->Array.NormalType = type;
- ctx->Array.NormalStride = stride;
- ctx->Array.NormalPtr = (void *) ptr;
- }
-
-
-
- void gl_ColorPointer( GLcontext *ctx,
- GLint size, GLenum type, GLsizei stride,
- const GLvoid *ptr )
- {
- if (size<3 || size>4) {
- gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
- return;
- }
- if (stride<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
- return;
- }
- switch (type) {
- case GL_BYTE:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLbyte);
- break;
- case GL_UNSIGNED_BYTE:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLubyte);
- break;
- case GL_SHORT:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLshort);
- break;
- case GL_UNSIGNED_SHORT:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLushort);
- break;
- case GL_INT:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLint);
- break;
- case GL_UNSIGNED_INT:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLuint);
- break;
- case GL_FLOAT:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLfloat);
- break;
- case GL_DOUBLE:
- ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLdouble);
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
- return;
- }
- ctx->Array.ColorSize = size;
- ctx->Array.ColorType = type;
- ctx->Array.ColorStride = stride;
- ctx->Array.ColorPtr = (void *) ptr;
- }
-
-
-
- void gl_IndexPointer( GLcontext *ctx,
- GLenum type, GLsizei stride, const GLvoid *ptr )
- {
- if (stride<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
- return;
- }
- switch (type) {
- case GL_SHORT:
- ctx->Array.IndexStrideB = stride ? stride : sizeof(GLbyte);
- break;
- case GL_INT:
- ctx->Array.IndexStrideB = stride ? stride : sizeof(GLint);
- break;
- case GL_FLOAT:
- ctx->Array.IndexStrideB = stride ? stride : sizeof(GLfloat);
- break;
- case GL_DOUBLE:
- ctx->Array.IndexStrideB = stride ? stride : sizeof(GLdouble);
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
- return;
- }
- ctx->Array.IndexType = type;
- ctx->Array.IndexStride = stride;
- ctx->Array.IndexPtr = (void *) ptr;
- }
-
-
-
- void gl_TexCoordPointer( GLcontext *ctx,
- GLint size, GLenum type, GLsizei stride,
- const GLvoid *ptr )
- {
- if (size<1 || size>4) {
- gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
- return;
- }
- switch (type) {
- case GL_SHORT:
- ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLshort);
- break;
- case GL_INT:
- ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLint);
- break;
- case GL_FLOAT:
- ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLfloat);
- break;
- case GL_DOUBLE:
- ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLdouble);
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
- return;
- }
- if (stride<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
- return;
- }
- ctx->Array.TexCoordSize = size;
- ctx->Array.TexCoordType = type;
- ctx->Array.TexCoordStride = stride;
- ctx->Array.TexCoordPtr = (void *) ptr;
- }
-
-
-
- void gl_EdgeFlagPointer( GLcontext *ctx,
- GLsizei stride, const GLboolean *ptr )
- {
- if (stride<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
- return;
- }
- ctx->Array.EdgeFlagStride = stride;
- ctx->Array.EdgeFlagStrideB = stride ? stride : sizeof(GLboolean);
- ctx->Array.EdgeFlagPtr = (GLboolean *) ptr;
- }
-
-
-
- /*
- * Execute
- */
- void gl_ArrayElement( GLcontext *ctx, GLint i )
- {
- struct vertex_buffer *VB = ctx->VB;
- GLint count = VB->Count;
-
- /* copy vertex data into the Vertex Buffer */
-
- if (ctx->Array.NormalEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.NormalPtr
- + i * ctx->Array.NormalStrideB;
- switch (ctx->Array.NormalType) {
- case GL_BYTE:
- VB->Normal[count][0] = BYTE_TO_FLOAT( p[0] );
- VB->Normal[count][1] = BYTE_TO_FLOAT( p[1] );
- VB->Normal[count][2] = BYTE_TO_FLOAT( p[2] );
- break;
- case GL_SHORT:
- VB->Normal[count][0] = SHORT_TO_FLOAT( ((GLshort*)p)[0] );
- VB->Normal[count][1] = SHORT_TO_FLOAT( ((GLshort*)p)[1] );
- VB->Normal[count][2] = SHORT_TO_FLOAT( ((GLshort*)p)[2] );
- break;
- case GL_INT:
- VB->Normal[count][0] = INT_TO_FLOAT( ((GLint*)p)[0] );
- VB->Normal[count][1] = INT_TO_FLOAT( ((GLint*)p)[1] );
- VB->Normal[count][2] = INT_TO_FLOAT( ((GLint*)p)[2] );
- break;
- case GL_FLOAT:
- VB->Normal[count][0] = ((GLfloat*)p)[0];
- VB->Normal[count][1] = ((GLfloat*)p)[1];
- VB->Normal[count][2] = ((GLfloat*)p)[2];
- break;
- case GL_DOUBLE:
- VB->Normal[count][0] = ((GLdouble*)p)[0];
- VB->Normal[count][1] = ((GLdouble*)p)[1];
- VB->Normal[count][2] = ((GLdouble*)p)[2];
- break;
- default:
- abort();
- }
- }
- else {
- VB->Normal[count][0] = ctx->Current.Normal[0];
- VB->Normal[count][1] = ctx->Current.Normal[0];
- VB->Normal[count][2] = ctx->Current.Normal[0];
- }
-
- /* TODO: directly set VB->Fcolor instead of calling a glColor command */
- if (ctx->Array.ColorEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB;
- switch (ctx->Array.ColorType) {
- case GL_BYTE:
- switch (ctx->Array.ColorSize) {
- case 4: glColor4bv( (GLbyte*) p ); break;
- case 3: glColor3bv( (GLbyte*) p ); break;
- }
- break;
- case GL_UNSIGNED_BYTE:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3ubv( (GLubyte*) p ); break;
- case 4: glColor4ubv( (GLubyte*) p ); break;
- }
- break;
- case GL_SHORT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3sv( (GLshort*) p ); break;
- case 4: glColor4sv( (GLshort*) p ); break;
- }
- break;
- case GL_UNSIGNED_SHORT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3usv( (GLushort*) p ); break;
- case 4: glColor4usv( (GLushort*) p ); break;
- }
- break;
- case GL_INT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3iv( (GLint*) p ); break;
- case 4: glColor4iv( (GLint*) p ); break;
- }
- break;
- case GL_UNSIGNED_INT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3uiv( (GLuint*) p ); break;
- case 4: glColor4uiv( (GLuint*) p ); break;
- }
- break;
- case GL_FLOAT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3fv( (GLfloat*) p ); break;
- case 4: glColor4fv( (GLfloat*) p ); break;
- }
- break;
- case GL_DOUBLE:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3dv( (GLdouble*) p ); break;
- case 4: glColor4dv( (GLdouble*) p ); break;
- }
- break;
- default:
- abort();
- }
- ctx->VB->MonoColor = GL_FALSE;
- }
- else {
- GLint shift = ctx->ColorShift;
- VB->Fcolor[count][0] = ctx->Current.IntColor[0] << shift;
- VB->Fcolor[count][1] = ctx->Current.IntColor[1] << shift;
- VB->Fcolor[count][2] = ctx->Current.IntColor[2] << shift;
- VB->Fcolor[count][3] = ctx->Current.IntColor[3] << shift;
- if (ctx->Light.ColorMaterialEnabled) {
- GLfloat color[4];
- color[0] = ctx->Current.IntColor[0] * ctx->Visual->InvRedScale;
- color[1] = ctx->Current.IntColor[1] * ctx->Visual->InvGreenScale;
- color[2] = ctx->Current.IntColor[2] * ctx->Visual->InvBlueScale;
- color[3] = ctx->Current.IntColor[3] * ctx->Visual->InvAlphaScale;
- gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
- }
- }
-
- if (ctx->Array.IndexEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB;
- switch (ctx->Array.IndexType) {
- case GL_SHORT:
- VB->Findex[count] = (GLuint) (*((GLshort*) p));
- break;
- case GL_INT:
- VB->Findex[count] = (GLuint) (*((GLint*) p));
- break;
- case GL_FLOAT:
- VB->Findex[count] = (GLuint) (*((GLfloat*) p));
- break;
- case GL_DOUBLE:
- VB->Findex[count] = (GLuint) (*((GLdouble*) p));
- break;
- default:
- abort();
- }
- ctx->VB->MonoColor = GL_FALSE;
- }
- else {
- VB->Findex[count] = ctx->Current.Index;
- }
-
- if (ctx->Array.TexCoordEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr
- + i * ctx->Array.TexCoordStrideB;
- VB->TexCoord[count][1] = 0.0F;
- VB->TexCoord[count][2] = 0.0F;
- VB->TexCoord[count][3] = 1.0F;
- switch (ctx->Array.TexCoordType) {
- case GL_SHORT:
- switch (ctx->Array.TexCoordSize) {
- /* FALL THROUGH! */
- case 4: VB->TexCoord[count][3] = ((GLshort*) p)[3];
- case 3: VB->TexCoord[count][2] = ((GLshort*) p)[2];
- case 2: VB->TexCoord[count][1] = ((GLshort*) p)[1];
- case 1: VB->TexCoord[count][0] = ((GLshort*) p)[0];
- }
- break;
- case GL_INT:
- switch (ctx->Array.TexCoordSize) {
- /* FALL THROUGH! */
- case 4: VB->TexCoord[count][3] = ((GLint*) p)[3];
- case 3: VB->TexCoord[count][2] = ((GLint*) p)[2];
- case 2: VB->TexCoord[count][1] = ((GLint*) p)[1];
- case 1: VB->TexCoord[count][0] = ((GLint*) p)[0];
- }
- break;
- case GL_FLOAT:
- switch (ctx->Array.TexCoordSize) {
- /* FALL THROUGH! */
- case 4: VB->TexCoord[count][3] = ((GLfloat*) p)[3];
- case 3: VB->TexCoord[count][2] = ((GLfloat*) p)[2];
- case 2: VB->TexCoord[count][1] = ((GLfloat*) p)[1];
- case 1: VB->TexCoord[count][0] = ((GLfloat*) p)[0];
- }
- break;
- case GL_DOUBLE:
- switch (ctx->Array.TexCoordSize) {
- /* FALL THROUGH! */
- case 4: VB->TexCoord[count][3] = ((GLdouble*) p)[3];
- case 3: VB->TexCoord[count][2] = ((GLdouble*) p)[2];
- case 2: VB->TexCoord[count][1] = ((GLdouble*) p)[1];
- case 1: VB->TexCoord[count][0] = ((GLdouble*) p)[0];
- }
- break;
- default:
- abort();
- }
- }
- else {
- COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
- }
-
- if (ctx->Array.EdgeFlagEnabled) {
- GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr
- + i * ctx->Array.EdgeFlagStrideB;
- VB->Edgeflag[count] = *((GLboolean*) b);
- }
- else {
- VB->Edgeflag[count] = ctx->Current.EdgeFlag;
- }
-
- if (ctx->Array.VertexEnabled) {
- GLbyte *b = (GLbyte*) ctx->Array.VertexPtr
- + i * ctx->Array.VertexStrideB;
- VB->Obj[count][2] = 0.0F;
- VB->Obj[count][3] = 1.0F;
- switch (ctx->Array.VertexType) {
- case GL_SHORT:
- switch (ctx->Array.VertexSize) {
- /* FALL THROUGH */
- case 4: VB->Obj[count][3] = ((GLshort*) b)[3];
- case 3: VB->Obj[count][2] = ((GLshort*) b)[2];
- case 2: VB->Obj[count][1] = ((GLshort*) b)[1];
- VB->Obj[count][0] = ((GLshort*) b)[0];
- }
- break;
- case GL_INT:
- switch (ctx->Array.VertexSize) {
- /* FALL THROUGH */
- case 4: VB->Obj[count][3] = ((GLint*) b)[3];
- case 3: VB->Obj[count][2] = ((GLint*) b)[2];
- case 2: VB->Obj[count][1] = ((GLint*) b)[1];
- VB->Obj[count][0] = ((GLint*) b)[0];
- }
- break;
- case GL_FLOAT:
- switch (ctx->Array.VertexSize) {
- /* FALL THROUGH */
- case 4: VB->Obj[count][3] = ((GLfloat*) b)[3];
- case 3: VB->Obj[count][2] = ((GLfloat*) b)[2];
- case 2: VB->Obj[count][1] = ((GLfloat*) b)[1];
- VB->Obj[count][0] = ((GLfloat*) b)[0];
- }
- break;
- case GL_DOUBLE:
- switch (ctx->Array.VertexSize) {
- /* FALL THROUGH */
- case 4: VB->Obj[count][3] = ((GLdouble*) b)[3];
- case 3: VB->Obj[count][2] = ((GLdouble*) b)[2];
- case 2: VB->Obj[count][1] = ((GLdouble*) b)[1];
- VB->Obj[count][0] = ((GLdouble*) b)[0];
- }
- break;
- default:
- abort();
- }
-
- /* Only store vertex if Vertex array pointer is enabled */
- count++;
- VB->Count = count;
- if (count==VB_MAX) {
- gl_transform_vb_part1( ctx, GL_FALSE );
- }
-
- }
- else {
- /* vertex array pointer not enabled: no vertex to process */
- }
- }
-
-
-
-
- /*
- * Save into display list
- * Use external API entry points since speed isn't too important here
- * and makes the code simpler. Also, if GL_COMPILE_AND_EXECUTE then
- * execute will happen too.
- */
- void gl_save_ArrayElement( GLcontext *ctx, GLint i )
- {
- if (ctx->Array.NormalEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.NormalPtr
- + i * ctx->Array.NormalStrideB;
- switch (ctx->Array.NormalType) {
- case GL_BYTE:
- glNormal3bv( (GLbyte*) p );
- break;
- case GL_SHORT:
- glNormal3sv( (GLshort*) p );
- break;
- case GL_INT:
- glNormal3iv( (GLint*) p );
- break;
- case GL_FLOAT:
- glNormal3fv( (GLfloat*) p );
- break;
- case GL_DOUBLE:
- glNormal3dv( (GLdouble*) p );
- break;
- default:
- abort();
- }
- }
-
- if (ctx->Array.ColorEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB;
- switch (ctx->Array.ColorType) {
- case GL_BYTE:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3bv( (GLbyte*) p ); break;
- case 4: glColor4bv( (GLbyte*) p ); break;
- }
- break;
- case GL_UNSIGNED_BYTE:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3ubv( (GLubyte*) p ); break;
- case 4: glColor4ubv( (GLubyte*) p ); break;
- }
- break;
- case GL_SHORT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3sv( (GLshort*) p ); break;
- case 4: glColor4sv( (GLshort*) p ); break;
- }
- break;
- case GL_UNSIGNED_SHORT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3usv( (GLushort*) p ); break;
- case 4: glColor4usv( (GLushort*) p ); break;
- }
- break;
- case GL_INT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3iv( (GLint*) p ); break;
- case 4: glColor4iv( (GLint*) p ); break;
- }
- break;
- case GL_UNSIGNED_INT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3uiv( (GLuint*) p ); break;
- case 4: glColor4uiv( (GLuint*) p ); break;
- }
- break;
- case GL_FLOAT:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3fv( (GLfloat*) p ); break;
- case 4: glColor4fv( (GLfloat*) p ); break;
- }
- break;
- case GL_DOUBLE:
- switch (ctx->Array.ColorSize) {
- case 3: glColor3dv( (GLdouble*) p ); break;
- case 4: glColor4dv( (GLdouble*) p ); break;
- }
- break;
- default:
- abort();
- }
- }
-
- if (ctx->Array.IndexEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB;
- switch (ctx->Array.IndexType) {
- case GL_SHORT:
- glIndexsv( (GLshort*) p );
- break;
- case GL_INT:
- glIndexiv( (GLint*) p );
- break;
- case GL_FLOAT:
- glIndexfv( (GLfloat*) p );
- break;
- case GL_DOUBLE:
- glIndexdv( (GLdouble*) p );
- break;
- default:
- abort();
- }
- }
-
- if (ctx->Array.TexCoordEnabled) {
- GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr
- + i * ctx->Array.TexCoordStrideB;
- switch (ctx->Array.TexCoordType) {
- case GL_SHORT:
- switch (ctx->Array.TexCoordSize) {
- case 1: glTexCoord1sv( (GLshort*) p ); break;
- case 2: glTexCoord2sv( (GLshort*) p ); break;
- case 3: glTexCoord3sv( (GLshort*) p ); break;
- case 4: glTexCoord4sv( (GLshort*) p ); break;
- }
- break;
- case GL_INT:
- switch (ctx->Array.TexCoordSize) {
- case 1: glTexCoord1iv( (GLint*) p ); break;
- case 2: glTexCoord2iv( (GLint*) p ); break;
- case 3: glTexCoord3iv( (GLint*) p ); break;
- case 4: glTexCoord4iv( (GLint*) p ); break;
- }
- break;
- case GL_FLOAT:
- switch (ctx->Array.TexCoordSize) {
- case 1: glTexCoord1fv( (GLfloat*) p ); break;
- case 2: glTexCoord2fv( (GLfloat*) p ); break;
- case 3: glTexCoord3fv( (GLfloat*) p ); break;
- case 4: glTexCoord4fv( (GLfloat*) p ); break;
- }
- break;
- case GL_DOUBLE:
- switch (ctx->Array.TexCoordSize) {
- case 1: glTexCoord1dv( (GLdouble*) p ); break;
- case 2: glTexCoord2dv( (GLdouble*) p ); break;
- case 3: glTexCoord3dv( (GLdouble*) p ); break;
- case 4: glTexCoord4dv( (GLdouble*) p ); break;
- }
- break;
- default:
- abort();
- }
- }
-
- if (ctx->Array.EdgeFlagEnabled) {
- GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr + i * ctx->Array.EdgeFlagStrideB;
- glEdgeFlagv( (GLboolean*) b );
- }
-
- if (ctx->Array.VertexEnabled) {
- GLbyte *b = (GLbyte*) ctx->Array.VertexPtr
- + i * ctx->Array.VertexStrideB;
- switch (ctx->Array.VertexType) {
- case GL_SHORT:
- switch (ctx->Array.VertexSize) {
- case 2: glVertex2sv( (GLshort*) b ); break;
- case 3: glVertex3sv( (GLshort*) b ); break;
- case 4: glVertex4sv( (GLshort*) b ); break;
- }
- break;
- case GL_INT:
- switch (ctx->Array.VertexSize) {
- case 2: glVertex2iv( (GLint*) b ); break;
- case 3: glVertex3iv( (GLint*) b ); break;
- case 4: glVertex4iv( (GLint*) b ); break;
- }
- break;
- case GL_FLOAT:
- switch (ctx->Array.VertexSize) {
- case 2: glVertex2fv( (GLfloat*) b ); break;
- case 3: glVertex3fv( (GLfloat*) b ); break;
- case 4: glVertex4fv( (GLfloat*) b ); break;
- }
- break;
- case GL_DOUBLE:
- switch (ctx->Array.VertexSize) {
- case 2: glVertex2dv( (GLdouble*) b ); break;
- case 3: glVertex3dv( (GLdouble*) b ); break;
- case 4: glVertex4dv( (GLdouble*) b ); break;
- }
- break;
- default:
- abort();
- }
- }
- }
-
-
-
- /*
- * Execute
- */
- void gl_DrawArrays( GLcontext *ctx,
- GLenum mode, GLint first, GLsizei count )
- {
- struct vertex_buffer* VB = ctx->VB;
-
- GLint i;
- GLboolean need_edges;
-
- if (INSIDE_BEGIN_END(ctx)) {
- gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
- return;
- }
- if (count<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
- return;
- }
-
- if (ctx->Primitive==GL_TRIANGLES || ctx->Primitive==GL_QUADS
- || ctx->Primitive==GL_POLYGON) {
- need_edges = GL_TRUE;
- }
- else {
- need_edges = GL_FALSE;
- }
-
- if (!ctx->Light.Enabled
- && !ctx->Texture.Enabled
- && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
- && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3
- && !ctx->Array.NormalEnabled
- && !ctx->Array.ColorEnabled
- && !ctx->Array.IndexEnabled
- && !ctx->Array.TexCoordEnabled
- && !ctx->Array.EdgeFlagEnabled) {
- /*
- * SPECIAL CASE: glVertex3fv() with no lighting
- */
- GLfloat (*vptr)[3];
- GLint remaining;
-
- gl_Begin( ctx, mode );
-
- remaining = count;
- vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr + 3 * first;
- while (remaining>0) {
- GLint vbspace, n;
-
- vbspace = VB_MAX - VB->Start;
- n = MIN2( vbspace, remaining );
-
- gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
-
- /* assign vertex colors */
- {
- GLint r = ctx->Current.IntColor[0] << ctx->ColorShift;
- GLint g = ctx->Current.IntColor[1] << ctx->ColorShift;
- GLint b = ctx->Current.IntColor[2] << ctx->ColorShift;
- GLint a = ctx->Current.IntColor[3] << ctx->ColorShift;
- GLint i, start = VB->Start;
- for (i=0;i<n;i++) {
- ASSIGN_4V( VB->Fcolor[start+i], r, g, b, a );
- }
- }
-
- /* assign polygon edgeflags */
- if (need_edges) {
- GLint i;
- for (i=0;i<n;i++) {
- VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
- }
- }
-
- remaining -= n;
-
- VB->Count = VB->Start + n;
- gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
- gl_render_vb( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
-
- vptr += n;
- }
-
- gl_End( ctx );
- }
- else if (!ctx->CompileFlag
- && ctx->Light.Enabled
- && !ctx->Texture.Enabled
- && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
- && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==4
- && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT
- && ctx->Array.NormalStride==0
- && !ctx->Array.ColorEnabled
- && !ctx->Array.IndexEnabled
- && !ctx->Array.TexCoordEnabled
- && !ctx->Array.EdgeFlagEnabled) {
- /*
- * SPECIAL CASE: glNormal3fv(); glVertex4fv(); with lighting
- */
- GLfloat (*vptr)[4], (*nptr)[3];
- GLint remaining;
-
- gl_Begin( ctx, mode );
-
- remaining = count;
- vptr = (GLfloat (*)[4]) ctx->Array.VertexPtr + 4 * first;
- nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr + 3 * first;
- while (remaining>0) {
- GLint vbspace, n;
-
- vbspace = VB_MAX - VB->Start;
- n = MIN2( vbspace, remaining );
-
- gl_xform_points_4fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
- gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr,
- ctx->Transform.Normalize );
-
- /* assign polygon edgeflags */
- if (need_edges) {
- GLint i;
- for (i=0;i<n;i++) {
- VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
- }
- }
-
- remaining -= n;
-
- VB->Count = VB->Start + n;
- gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
- gl_render_vb( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
-
- vptr += n;
- nptr += n;
- }
-
- gl_End( ctx );
- }
- else if (!ctx->CompileFlag
- && ctx->Light.Enabled
- && !ctx->Texture.Enabled
- && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
- && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3
- && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT
- && ctx->Array.NormalStride==0
- && !ctx->Array.ColorEnabled
- && !ctx->Array.IndexEnabled
- && !ctx->Array.TexCoordEnabled
- && !ctx->Array.EdgeFlagEnabled) {
- /*
- * SPECIAL CASE: glNormal3fv(); glVertex3fv(); with lighting
- */
- GLfloat (*vptr)[3], (*nptr)[3];
- GLint remaining;
-
- gl_Begin( ctx, mode );
-
- remaining = count;
- vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr + 3 * first;
- nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr + 3 * first;
- while (remaining>0) {
- GLint vbspace, n;
-
- vbspace = VB_MAX - VB->Start;
- n = MIN2( vbspace, remaining );
-
- gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
- gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr,
- ctx->Transform.Normalize );
-
- /* assign polygon edgeflags */
- if (need_edges) {
- GLint i;
- for (i=0;i<n;i++) {
- VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
- }
- }
-
- remaining -= n;
-
- VB->Count = VB->Start + n;
- gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
- gl_render_vb( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
-
- vptr += n;
- nptr += n;
- }
-
- gl_End( ctx );
- }
- else {
- /*
- * GENERAL CASE:
- */
- gl_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_ArrayElement( ctx, first+i );
- }
- gl_End( ctx );
- }
- }
-
-
-
- /*
- * Save into a display list
- */
- void gl_save_DrawArrays( GLcontext *ctx,
- GLenum mode, GLint first, GLsizei count )
- {
- GLint i;
-
- if (INSIDE_BEGIN_END(ctx)) {
- gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
- return;
- }
- if (count<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
- return;
- }
- switch (mode) {
- case GL_POINTS:
- case GL_LINES:
- case GL_LINE_STRIP:
- case GL_LINE_LOOP:
- case GL_TRIANGLES:
- case GL_TRIANGLE_STRIP:
- case GL_TRIANGLE_FAN:
- case GL_QUADS:
- case GL_QUAD_STRIP:
- case GL_POLYGON:
- /* OK */
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
- return;
- }
-
-
- /* Note: this will do compile AND execute if needed */
- gl_save_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_save_ArrayElement( ctx, first+i );
- }
- gl_save_End( ctx );
- }
-
-
-
-
- /*
- * Execute only
- */
- void gl_DrawElements( GLcontext *ctx,
- GLenum mode, GLsizei count,
- GLenum type, const GLvoid *indices )
- {
-
- if (INSIDE_BEGIN_END(ctx)) {
- gl_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
- return;
- }
- if (count<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
- return;
- }
- switch (mode) {
- case GL_POINTS:
- case GL_LINES:
- case GL_LINE_STRIP:
- case GL_LINE_LOOP:
- case GL_TRIANGLES:
- case GL_TRIANGLE_STRIP:
- case GL_TRIANGLE_FAN:
- case GL_QUADS:
- case GL_QUAD_STRIP:
- case GL_POLYGON:
- /* OK */
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
- return;
- }
- switch (type) {
- case GL_UNSIGNED_BYTE:
- {
- GLubyte *ub_indices = (GLubyte *) indices;
- GLint i;
- gl_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_ArrayElement( ctx, (GLint) ub_indices[i] );
- }
- gl_End( ctx );
- }
- break;
- case GL_UNSIGNED_SHORT:
- {
- GLushort *us_indices = (GLushort *) indices;
- GLint i;
- gl_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_ArrayElement( ctx, (GLint) us_indices[i] );
- }
- gl_End( ctx );
- }
- break;
- case GL_UNSIGNED_INT:
- {
- GLuint *ui_indices = (GLuint *) indices;
- GLint i;
- gl_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_ArrayElement( ctx, (GLint) ui_indices[i] );
- }
- gl_End( ctx );
- }
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
- return;
- }
- }
-
-
-
-
- /*
- * Save (and perhaps execute)
- */
- void gl_save_DrawElements( GLcontext *ctx,
- GLenum mode, GLsizei count,
- GLenum type, const GLvoid *indices )
- {
- switch (type) {
- case GL_UNSIGNED_BYTE:
- {
- GLubyte *ub_indices = (GLubyte *) indices;
- GLint i;
- gl_save_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_save_ArrayElement( ctx, (GLint) ub_indices[i] );
- }
- gl_save_End( ctx );
- }
- break;
- case GL_UNSIGNED_SHORT:
- {
- GLushort *us_indices = (GLushort *) indices;
- GLint i;
- gl_save_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_save_ArrayElement( ctx, (GLint) us_indices[i] );
- }
- gl_save_End( ctx );
- }
- break;
- case GL_UNSIGNED_INT:
- {
- GLuint *ui_indices = (GLuint *) indices;
- GLint i;
- gl_save_Begin( ctx, mode );
- for (i=0;i<count;i++) {
- gl_save_ArrayElement( ctx, (GLint) ui_indices[i] );
- }
- gl_save_End( ctx );
- }
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
- return;
- }
- }
-
-
-
-
- void gl_InterleavedArrays( GLcontext *ctx,
- GLenum format, GLsizei stride,
- const GLvoid *pointer )
- {
- GLboolean tflag, cflag, nflag; /* enable/disable flags */
- GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
- GLenum ctype; /* color type */
- GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
- GLint defstride; /* default stride */
- GLint c, f;
-
- f = sizeof(GLfloat);
- c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
-
- if (stride<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
- return;
- }
-
- switch (format) {
- case GL_V2F:
- tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
- tcomps = 0; ccomps = 0; vcomps = 2;
- voffset = 0;
- defstride = 2*f;
- break;
- case GL_V3F:
- tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
- tcomps = 0; ccomps = 0; vcomps = 3;
- voffset = 0;
- defstride = 3*f;
- break;
- case GL_C4UB_V2F:
- tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
- tcomps = 0; ccomps = 4; vcomps = 2;
- ctype = GL_UNSIGNED_BYTE;
- coffset = 0;
- voffset = c;
- defstride = c + 2*f;
- break;
- case GL_C4UB_V3F:
- tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
- tcomps = 0; ccomps = 4; vcomps = 3;
- ctype = GL_UNSIGNED_BYTE;
- coffset = 0;
- voffset = c;
- defstride = c + 3*f;
- break;
- case GL_C3F_V3F:
- tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
- tcomps = 0; ccomps = 3; vcomps = 3;
- ctype = GL_FLOAT;
- coffset = 0;
- voffset = 3*f;
- defstride = 6*f;
- break;
- case GL_N3F_V3F:
- tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
- tcomps = 0; ccomps = 0; vcomps = 3;
- noffset = 0;
- voffset = 3*f;
- defstride = 6*f;
- break;
- case GL_C4F_N3F_V3F:
- tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
- tcomps = 0; ccomps = 4; vcomps = 3;
- ctype = GL_FLOAT;
- coffset = 0;
- noffset = 4*f;
- voffset = 7*f;
- defstride = 10*f;
- break;
- case GL_T2F_V3F:
- tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
- tcomps = 2; ccomps = 0; vcomps = 3;
- voffset = 2*f;
- defstride = 5*f;
- break;
- case GL_T4F_V4F:
- tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
- tcomps = 4; ccomps = 0; vcomps = 4;
- voffset = 4*f;
- defstride = 8*f;
- break;
- case GL_T2F_C4UB_V3F:
- tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
- tcomps = 2; ccomps = 4; vcomps = 3;
- ctype = GL_UNSIGNED_BYTE;
- coffset = 2*f;
- voffset = c+2*f;
- defstride = c+5*f;
- break;
- case GL_T2F_C3F_V3F:
- tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
- tcomps = 2; ccomps = 3; vcomps = 3;
- ctype = GL_FLOAT;
- coffset = 2*f;
- voffset = 5*f;
- defstride = 8*f;
- break;
- case GL_T2F_N3F_V3F:
- tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
- tcomps = 2; ccomps = 0; vcomps = 3;
- noffset = 2*f;
- voffset = 5*f;
- defstride = 8*f;
- break;
- case GL_T2F_C4F_N3F_V3F:
- tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
- tcomps = 2; ccomps = 4; vcomps = 3;
- ctype = GL_FLOAT;
- coffset = 2*f;
- noffset = 6*f;
- voffset = 9*f;
- defstride = 12*f;
- break;
- case GL_T4F_C4F_N3F_V4F:
- tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
- tcomps = 4; ccomps = 4; vcomps = 4;
- ctype = GL_FLOAT;
- coffset = 4*f;
- noffset = 8*f;
- voffset = 11*f;
- defstride = 15*f;
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
- return;
- }
-
- if (stride==0) {
- stride = defstride;
- }
-
- gl_DisableClientState( ctx, GL_EDGE_FLAG_ARRAY );
- gl_DisableClientState( ctx, GL_INDEX_ARRAY );
-
- if (tflag) {
- gl_EnableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
- gl_TexCoordPointer( ctx, tcomps, GL_FLOAT, stride, pointer );
- }
- else {
- gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
- }
-
- if (cflag) {
- gl_EnableClientState( ctx, GL_COLOR_ARRAY );
- gl_ColorPointer( ctx, ccomps, ctype, stride,
- (GLubyte*) pointer + coffset );
- }
- else {
- gl_DisableClientState( ctx, GL_COLOR_ARRAY );
- }
-
- if (nflag) {
- gl_EnableClientState( ctx, GL_NORMAL_ARRAY );
- gl_NormalPointer( ctx, GL_FLOAT, stride,
- (GLubyte*) pointer + noffset );
- }
- else {
- gl_DisableClientState( ctx, GL_NORMAL_ARRAY );
- }
-
- gl_EnableClientState( ctx, GL_VERTEX_ARRAY );
- gl_VertexPointer( ctx, vcomps, GL_FLOAT, stride,
- (GLubyte *) pointer + voffset );
- }
-
-
-
- void gl_save_InterleavedArrays( GLcontext *ctx,
- GLenum format, GLsizei stride,
- const GLvoid *pointer )
- {
- /* Just execute since client-side state changes aren't put in
- * display lists.
- */
- gl_InterleavedArrays( ctx, format, stride, pointer );
- }
-
-